<script setup lang="ts">
import {DownOutlined} from "@ant-design/icons-vue";

const props = defineProps({
  placement: {
    type: String,
    default: 'bottomLeft'
  },
  name: {
    type: String,
    default: ''
  },
  value: {
    type: [Array],
    default: () => []
  },
  items: {
    type: Array,
    default: () => ([])
  },
  valueName: {
    type: String,
    default: 'id'
  },
  labelName: {
    type: String,
    default: 'title'
  },
  descName: {
    type: String,
    default: 'desc'
  },
  confirm: {
    type: Boolean,
    default: false
  }
});
const emit = defineEmits(['change', 'update:value']);
const selected = ref<any[]>([]);
const open = ref(false);
// 如果传入了value，就用value，否则用selected
watch(() => props.value, (value) => {
  if (value.length) {
    selected.value = value;
  } else {
    selected.value = props.items.map((item: any) => item[props.valueName]);
  }
})
watch(() => props.items, (items) => {
  if (items) {
    loadData();
  }
})
const change = () => {
  nextTick(() => {
    emit('change', selected.value);
    emit('update:value', selected.value);
    if (props.confirm){
      open.value = false;
    }
  })
}
const loadData = () => {
  if (props.value.length) {
    selected.value = props.value;
  } else {
    selected.value = props.items.map((item: any) => item[props.valueName]);
    change();
  }
}
loadData();
watch(() => open.value, (value) => {
  if (value) {
    if (props.value.length) {
      selected.value = props.value;
    } else {
      selected.value = props.items.map((item: any) => item[props.valueName]);
    }
  }
})
// 选中项修改时，触发change事件
watch(() => selected.value, (value, old) => {
  // 至少选中一个，如果没有选中的 无效
  if (value.length === 0) {
    selected.value = old;
  }
  if (!props.confirm) {
    change();
  }
})
</script>

<template>
  <a-dropdown v-model:open="open" :placement="placement" arrow trigger="click">
    <template #overlay>
      <a-menu>
        <a-row>
          <a-space>

            <a-button type="link" size="small" @click="()=>{
            selected = items.map(item=>item[valueName])
          }"
            >全选
            </a-button>
            <a-button type="link" size="small" @click="()=>{
            selected = [items[0][valueName]]
          }"
            >清空
            </a-button>
          </a-space>
        </a-row>
        <a-divider style="    margin: 5px 0 0 0;"/>
        <a-checkbox-group v-model:value="selected" style="display: block">
          <a-menu-item v-for="(item,index) in items" :key="item[props.valueName]">
            <a-checkbox :value="item[props.valueName]">
              <span>{{ item[props.labelName] }}</span>
              <span class="desc" v-if="typeof item[props.descName]!=='undefined'">({{ item[props.descName] }})</span>
            </a-checkbox>
          </a-menu-item>
        </a-checkbox-group>
        <a-divider style="margin: 0 0 5px 0;" v-if="confirm"/>
        <a-row type="flex" v-if="confirm">
          <a-col flex="1"></a-col>
          <a-col>
            <a-space>
              <a-button size="small" type="default" @click="()=>open=false">取消</a-button>
              <a-button size="small" type="primary" @click="change">确定</a-button>
            </a-space>
          </a-col>
        </a-row>
      </a-menu>
    </template>
    <a-button type="default" size="small">
      <div class="label" v-if="!open">
        {{
          value.length === items.length ? ('全部' + name) : items.filter((item: any) => value.includes(item[props.valueName])).map((item: any) => item[props.labelName]).join(',')
        }}
      </div>
      <div class="label" v-else>
        {{
          selected.length === items.length ? ('全部' + name) : items.filter((item: any) => selected.includes(item[props.valueName])).map((item: any) => item[props.labelName]).join(',')
        }}
      </div>
      <DownOutlined/>
    </a-button>
  </a-dropdown>
</template>

<style lang="less" scoped>
.label {
  display: inline-block;
  vertical-align: top;
  max-width: 120px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  padding-right: 5px;
}

.desc {
  font-size: 12px;
  color: #999;
}
</style>
